/**
 * PENDING代表等待，FULFILLED代表请求成功，FAILED代表请求失败或无法完成请求
 * @type {string}
 */
const PENDING = 'pending', FULFILLED = 'fulfilled',
    FAILED = 'failed';
class MyPromise  {
    status = PENDING;
    /** constructor的作用：当执行new MyPromise(functor)的时候，
     * 传入一个函数类的functor变量，使functor函数立即执行 */
    constructor (functor) {
        try {
            functor(this.resolve, this.reject);
        } catch (e) {
            this.reject(e);
        }
    }

    /**
     * 请求成功的函数（仅在当前状态为pending的时候去执行）
     * @param result
     */
    resolve = (result) => {
        if (this.status === PENDING) {
            this.status = FULFILLED;
            //console.log('成功回调');

            let _this = this; //是为setTimeout的异步函数引用当前的MyPromise对象
            setTimeout(() => {
                let currentPromise = _this;
                let currentValue = result;
                try {
                    while (currentPromise !== undefined) {
                        if (currentPromise.succeedCallback)
                            currentValue = currentPromise.succeedCallback(currentValue);
                        //当前级别的promise类执行完毕的时候，引用它的子类
                        currentPromise = currentPromise.$child;
                    }
                } catch (e) { //捕获异常部分
                    while (currentPromise !== undefined) {
                        if (currentPromise.failedCallback)
                            currentValue = currentPromise.failedCallback(e);
                        //当前级别的promise类执行完毕的时候，引用它的子类
                        currentPromise = currentPromise.$child;
                    }
                }
            }, 0);
        }
    };


    /**
     * 请求失败的函数（仅在当前状态为pending的时候去执行）
     * @param reason
     */
    reject = (reason) => {
        if (this.status === PENDING) {
            this.status = FAILED;
            //console.log(`失败回调：\n${reason}`);

            let _this = this;
            setTimeout(() => {
                let currentReason = reason;
                let currentPromise = _this;
                while (currentPromise !== undefined) {
                    if (currentPromise.failedCallback){
                        currentPromise.failedCallback(currentReason);
                        return;
                    }
                    //当前级别的promise类执行完毕的时候，引用它的子类
                    currentPromise = currentPromise.$child;
                }
            });
        }
    };

    /**
     * 这里，$root代表链式MyPromise对象的根，
     * $parent代表链式MyPromise对象的父级，
     * $child代表链式MyPromise对象的子级，
     * 三个变量的设置的作用：当父级以上的MyPromise对象捕获异常的时候，
     * 能够调用子级的catch方法。
     * @type {undefined}
     */
    $root = undefined;
    $parent = undefined;
    $child = undefined;
    /**
     * 每一个MyPromise类对象都有succeededCallback和failedCallback两种属性，
     * 分别被resolve和reject方法调用
     * */
    succeedCallback = undefined;
    failedCallback = undefined;
    /** 每一个MyPromise类对象都有then和catch的方法，用于进行链式调用。
     * then和catch的方法。
     * 代码的执行步骤是：
     * 1.新建一个MyPromise对象
     * 2.在当前的MyPromise对象中的$child属性设为新建的MyPromise对象
     * 3.在新建的MyPromise对象中的$parent属性设为当前的MyPromise对象
     * 4.指定一个根MyPromise对象，并依次向它的子级MyPromise对象设置根MyPromise对象
     * 5.返回新建的MyPromise对象 */
    then = (succeedFun, failedFun) => {
        this.succeedCallback = succeedFun;
        this.failedCallback = failedFun;
        let np = new MyPromise((resolve, reject) => {

        });
        this.$child = np;
        np.$parent = this;
        if (!this.$root) this.$root = this;
        np.$root = this.$root;
        return np;
    };
    catch = (failedFun) => {
        this.failedCallback = failedFun;
        let np = new MyPromise((resolve, reject) => {

        });
        this.$child = np;
        np.$parent = this;
        if (!this.$root) this.$root = this;
        np.$root = this.$root;
        return np;
    };
}

module.exports = MyPromise;